package main

import (
	"context"
	"fmt"
	"log"
	"net"
	"strconv"

	"learn-go-demo/pkg/config"
	"learn-go-demo/pkg/database"
	"learn-go-demo/pkg/discovery"
	httpHandler "learn-go-demo/pkg/http"
	"learn-go-demo/pkg/models"
	pb "learn-go-demo/proto"

	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/credentials/insecure"
	"google.golang.org/grpc/status"
)

type OrderServer struct {
	pb.UnimplementedOrderServiceServer
	userClient pb.UserServiceClient
	orderRepo  *models.OrderRepository
}

func (s *OrderServer) CreateOrder(ctx context.Context, req *pb.CreateOrderRequest) (*pb.CreateOrderResponse, error) {
	// 调用用户服务验证用户
	userResp, err := s.userClient.GetUser(ctx, &pb.GetUserRequest{Id: req.UserId})
	if err != nil {
		log.Printf("Failed to get user: %v", err)
		return nil, status.Errorf(codes.NotFound, "User not found")
	}

	log.Printf("Creating order for user: %s", userResp.Name)

	// 创建订单
	order := &models.Order{
		UserID:  int64(req.UserId),
		Product: req.Product,
		Amount:  req.Amount,
		Status:  "pending",
	}

	err = s.orderRepo.Create(order)
	if err != nil {
		log.Printf("Failed to create order: %v", err)
		return nil, status.Errorf(codes.Internal, "Failed to create order")
	}

	return &pb.CreateOrderResponse{
		OrderId: int32(order.ID),
		Message: "Order created successfully",
	}, nil
}

func (s *OrderServer) GetOrder(ctx context.Context, req *pb.GetOrderRequest) (*pb.GetOrderResponse, error) {
	order, err := s.orderRepo.GetByID(int64(req.OrderId))
	if err != nil {
		log.Printf("Failed to get order: %v", err)
		return nil, status.Errorf(codes.NotFound, "Order not found")
	}

	return &pb.GetOrderResponse{
		OrderId: int32(order.ID),
		UserId:  int32(order.UserID),
		Product: order.Product,
		Amount:  order.Amount,
	}, nil
}

func main() {
	// 加载配置 - 使用订单服务专用配置
	cfg, err := config.LoadConfig("./configs")
	if err != nil {
		log.Fatalf("Failed to load config: %v", err)
	}

	// 订单服务使用不同的端口
	cfg.GRPC.Port = 50052
	cfg.HTTP.Port = 8082
	cfg.App.Name = "order-service"

	log.Printf("Starting %s v%s in %s mode", cfg.App.Name, cfg.App.Version, cfg.App.Environment)

	// 初始化数据库连接
	db, err := database.NewMySQLConnection(cfg.Database)
	if err != nil {
		log.Fatalf("Failed to connect to database: %v", err)
	}
	defer db.Close()

	// 初始化订单仓库
	orderRepo := models.NewOrderRepository(db)

	// 创建表（如果不存在）
	if err := orderRepo.CreateTable(); err != nil {
		log.Fatalf("Failed to create order table: %v", err)
	}

	registry := discovery.NewServiceRegistry()

	// 发现用户服务
	userAddrs, err := registry.Discover("user-service")
	if err != nil || len(userAddrs) == 0 {
		log.Fatalf("Failed to discover user service: %v", err)
	}

	// 连接用户服务
	conn, err := grpc.Dial(userAddrs[0], grpc.WithTransportCredentials(insecure.NewCredentials()))
	if err != nil {
		log.Fatalf("Failed to connect to user service: %v", err)
	}
	defer conn.Close()

	userClient := pb.NewUserServiceClient(conn)

	grpcPort := fmt.Sprintf(":%d", cfg.GRPC.Port)
	lis, err := net.Listen("tcp", grpcPort)
	if err != nil {
		log.Fatalf("Failed to listen: %v", err)
	}

	serviceAddr := fmt.Sprintf("localhost:%d", cfg.GRPC.Port)
	err = registry.Register("order-service", serviceAddr, 30)
	if err != nil {
		log.Fatalf("Failed to register service: %v", err)
	}

	// 启动 gRPC 服务器
	s := grpc.NewServer()
	pb.RegisterOrderServiceServer(s, &OrderServer{
		userClient: userClient,
		orderRepo:  orderRepo,
	})

	// 启动 HTTP 服务器
	go func() {
		router := httpHandler.SetupRouter()
		orderHandler := httpHandler.NewOrderHandler(orderRepo, userClient)
		httpHandler.SetupOrderRoutes(router, orderHandler)

		httpPort := strconv.Itoa(cfg.HTTP.Port)
		log.Printf("Order HTTP server starting on :%s", httpPort)
		httpHandler.StartServer(router, httpPort)
	}()

	log.Printf("Order gRPC service starting on %s", grpcPort)
	if err := s.Serve(lis); err != nil {
		log.Fatalf("Failed to serve: %v", err)
	}
}
